from pandac.PandaModules import QueuedConnectionManager
from pandac.PandaModules import QueuedConnectionListener,PointerToConnection,NetAddress
from pandac.PandaModules import QueuedConnectionReader
from pandac.PandaModules import ConnectionWriter
from QNetwork import QNetwork
# task define
from TaskDefine import task_LISTENERPOLLING
from direct.task import Task

class QServer(QNetwork):
    backlog = 1000 #If we ignore 1,000 connection attempts, something is wrong!
    def Setup(self,
              acceptedConnectionNum,
              port_address=QNetwork.default_Port):
        self.cManager = QueuedConnectionManager()
        self.cListener = QueuedConnectionListener(self.cManager, 0)
        self.cReader = QueuedConnectionReader(self.cManager, 0)
        self.cWriter = ConnectionWriter(self.cManager,0)
        self.tcpSocket = self.cManager.openTCPServerRendezvous(port_address, QServer.backlog)
        self.tcpSocket.setNoDelay(True)
        self.cListener.addConnection(self.tcpSocket)
        self.ConnectionTargetDictReset(acceptedConnectionNum)
        # add task
        self.HasTskListener = False
        if self.TargetIDMgr.HasValidID():
            self.AddTskListener()
        self.ReaderPollingEnable()

        self.ListenerEnable = True   # self.ListenerEnable = False when game started
        return True

    # connection listen task
    def tskListenerPolling(self, task):
        if self.cListener.newConnectionAvailable():
            rendezvous = PointerToConnection()
            netAddress = NetAddress()
            client = PointerToConnection()

            if self.cListener.getNewConnection(rendezvous,netAddress,client):
                client = client.p()
                self.cReader.addConnection(client)
                i = self.ConnectionTargetAdd(client)
                self.NewConnectionHandle(i)
                if not self.TargetIDMgr.HasValidID():
                    self.RemoveTskListener()

        ret = task.cont if self.HasTskListener else task.done
        return ret

    def AddTskListener(self):
        if not self.HasTskListener:
            print "open tskListenerPolling"
            #self.cListener.addConnection(self.tcpSocket)
            self._taskMgr.Add(self.tskListenerPolling, task_LISTENERPOLLING["name"], task_LISTENERPOLLING["sort"])
            self.HasTskListener = True

    def RemoveTskListener(self):
        if self.HasTskListener:
            print "close tskListenerPolling"
            #self.cListener.removeConnection(self.tcpSocket)
            self._taskMgr.Remove(task_LISTENERPOLLING["name"])
            self.HasTskListener = False

    # used in game and lobby
    def ConnectionRemove(self, removeList):
        QNetwork.ConnectionRemove(self, removeList)
        if self.ListenerEnable: # has a valid id
            self.AddTskListener()

    def SlotClose(self):
        # only can close non-member slot
        self.TargetIDMgr.CloseIDSlot()
        if not self.TargetIDMgr.HasValidID():
            self.RemoveTskListener()

    def SlotOpen(self):
        self.TargetIDMgr.OpenIDSlot()
        self.AddTskListener()

    def DisableListener(self):
        self.RemoveTskListener()
        self.ListenerEnable = False
